"""
ProjectName:qq_tools_bot 
FileName:merge_picture.py
IdeaName:PyCharm 
UserName:zhao
UserMail:2909552840@qq.com
UserHomepage:https://www.zywi.cn
CreationTime:2024/10/30 下午4:20  
"""
import os
import shutil
import time
import uuid
from typing import Optional

import requests

from api import MessageApi
from models import MessageReport, MessageType, Message, MsType, MsData
from utils import print_red, print_blue


class MergeResults:
    """
    合并结果
    """
    status: Optional[bool] = False
    message: Optional[str] = ''
    url: Optional[str] = ''


class MergePicture:
    """
    合图功能
    """

    def __init__(self, message_report: MessageReport, message_api: MessageApi):
        """
        初始化函数
        :param message_report: 消息上报
        :param message_api: 消息API
        """
        super().__init__()
        self.message_report = message_report
        self.message_api = message_api
        # QQ
        user_id = self.message_report.user_id
        # 获取当前运行目录
        config_path = f'{os.getcwd()}\\data\\image\\{user_id}\\'
        self.picture_stitching(config_path)
        self.picture_record(config_path)
        self.left_right_picture(config_path)
        self.top_bottom_picture(config_path)
        self.clear(config_path)

    def picture_stitching(self, config_path: str) -> None:
        """
        图片拼接
        :return:
        """
        # 原始消息
        raw_message = self.message_report.raw_message
        if raw_message == '图片拼接':
            # 判断文件是否存在
            if not os.path.isdir(config_path):
                # 不存在 创建目录
                os.makedirs(os.path.dirname(config_path), exist_ok=True)
            else:
                # 存在 删除目录
                shutil.rmtree(config_path)

    def left_right_picture(self, config_path: str) -> None:
        """
        左右拼接
        :return:
        """
        # 原始消息
        raw_message = self.message_report.raw_message
        if raw_message == '左右拼接':
            # 判断文件是否存在
            if os.path.isdir(config_path):
                user_id = self.message_report.user_id
                group_id = self.message_report.group_id
                # 获取目录下的所有文件
                image_list = os.listdir(config_path)
                # 图片路径
                image_paths = [os.path.join(config_path, image) for image in image_list]
                # 合并图片
                res = self.merge_images(image_paths, vertical=False)
                # 判断是否合并成功
                self.is_merge(config_path=config_path, user_id=user_id, group_id=group_id, res=res)

    def top_bottom_picture(self, config_path: str) -> None:
        """
        上下拼接
        :return:
        """
        # 原始消息
        raw_message = self.message_report.raw_message
        if raw_message == '上下拼接':
            # 判断文件是否存在
            if os.path.isdir(config_path):
                user_id = self.message_report.user_id
                group_id = self.message_report.group_id
                # 获取目录下的所有文件
                image_list = os.listdir(config_path)
                # 图片路径
                image_paths = [os.path.join(config_path, image) for image in image_list]
                # 合并图片
                res = self.merge_images(image_paths, vertical=True)
                # 判断是否合并成功
                self.is_merge(config_path=config_path, user_id=user_id, group_id=group_id, res=res)

    def clear(self, config_path: str) -> None:
        """
        清除缓存
        :return:
        """
        # 原始消息
        raw_message = self.message_report.raw_message
        if raw_message == '图片拼接清除':
            # 判断文件是否存在
            if os.path.isdir(config_path):
                # 存在 删除目录
                shutil.rmtree(config_path)

    def download_image(self, url: str, save_directory: str) -> bool:
        """
        下载图片
        :param url: 图片的 URL
        :param save_directory: 保存目录
        :return: 下载是否成功
        """
        try:
            # 创建保存目录（如果不存在的话）
            os.makedirs(save_directory, exist_ok=True)

            unique_id = uuid.uuid4()
            timestamp = time.strftime('%Y%m%d_%H%M%S') + str(unique_id)[:6]
            filename = f'image_{timestamp}.jpg'  # 根据需要修改扩展名

            # 获取图片的完整路径
            file_path = os.path.join(save_directory, filename)

            # 发送 GET 请求下载图片
            response = requests.get(url)

            # 检查请求是否成功
            if response.ok:
                with open(file_path, 'wb') as file:
                    file.write(response.content)
                print_blue(f"Image downloaded and saved to: {file_path}")
                return True
            else:
                print_red(f"Failed to download image. Status code: {response.status_code}")
                return False
        except Exception as e:
            print_red(f"Error: {e}")
            return False

    def picture_record(self, config_path: str) -> None:
        """
        图片记录
        :param config_path: 保存图片的配置路径
        """
        # 原始消息和消息内容
        raw_message = self.message_report.raw_message
        message = self.message_report.message

        # 关键词列表
        keywords = ['图片拼接', '左右拼接', '上下拼接', '图片拼接清除']
        if raw_message in keywords:
            return

        # 检查配置路径是否为目录
        if os.path.isdir(config_path):
            for image in message:
                if image.type == MsType.IMAGE:
                    file = image.data.file

                    # 判断图片的后缀是否是支持的格式
                    if not file.lower().endswith(('.jpg', '.png', '.jpeg')):
                        self._send_unsupported_format_message()
                    else:
                        # 下载图片
                        url = image.data.url.replace('https://', 'http://')
                        self.download_image(url, config_path)

    def _send_unsupported_format_message(self) -> None:
        """
        发送图片格式不支持的消息
        """
        user_id = self.message_report.user_id
        group_id = self.message_report.group_id

        if self.message_report.message_type == MessageType.GROUP:
            # 创建 @ 消息
            message_at = Message()
            message_at.type = MsType.AT
            message_at.data = MsData(qq=user_id)

            # 创建文本消息
            message_text = Message()
            message_text.type = MsType.TEXT
            message_text.data = MsData(text='图片格式不支持, 请上传.jpg, .png, .jpeg格式的图片')

            self.message_api.send_group_msg(group_id, [message_at, message_text])
        elif self.message_report.message_type == MessageType.PRIVATE:
            # 发送私聊消息
            message = Message()
            message.type = MsType.TEXT
            message.data = MsData(text='图片格式不支持, 请上传.jpg, .png, .jpeg格式的图片')
            self.message_api.send_private_msg(user_id, [message])

    def merge_images(self, image_paths: list, vertical: bool = False) -> MergeResults:
        """
        合并多张图像
        :param image_paths: 图像文件路径列表
        :param vertical: 是否垂直合并
        :return: MergeResults 对象
        """
        merge_results = MergeResults()
        url = "https://api.zgfxk.cn/api/apitools/im"

        # 准备请求参数
        payload = {
            'type': 'file',
            'vh': 'v' if vertical else 'h'
        }

        # 准备文件列表
        files = [('images[]', (path, open(path, 'rb'), 'image/jpeg')) for path in image_paths]

        try:
            response = requests.post(url, data=payload, files=files)

            # 处理响应
            if response.status_code == 200:
                json_response = response.json()
                merge_results.status = json_response.get('code') == 1
                merge_results.message = json_response.get('msg')

                if merge_results.status:
                    merge_results.url = json_response.get('data', {}).get('url')
                    print_blue('拼接状态:', merge_results.message)
                    print_blue('拼接图片链接:', merge_results.url)
                else:
                    print_red('Error:', merge_results.message)
            else:
                error_message = f"Failed to merge images. Status code: {response.status_code}"
                print_red(error_message)
                merge_results.status = False
                merge_results.message = error_message

        except Exception as e:
            error_message = f"Error: {e}"
            print_red(error_message)
            merge_results.status = False
            merge_results.message = error_message

        return merge_results

    def is_merge(self, config_path: [], user_id: int, group_id: int, res: MergeResults):
        if res.status:
            if self.message_report.message_type == MessageType.GROUP:
                # 回复·群聊消息
                # 创建 @ 消息
                message_at = Message()
                message_at.type = MsType.AT
                message_at.data = MsData(qq=user_id)
                # 创建图片消息
                message_image = Message()
                message_image.type = MsType.IMAGE
                message_image.data = MsData(file=res.url)
                self.message_api.send_group_msg(group_id, [message_at, message_image])
            elif self.message_report.message_type == MessageType.PRIVATE:
                # 回复·私聊消息
                message = Message()
                message.type = MsType.IMAGE
                message.data = MsData(file=res.url)
                self.message_api.send_private_msg(user_id, [message])
        else:
            # 拼接失败
            if self.message_report.message_type == MessageType.GROUP:
                # 回复·群聊消息
                # 创建 @ 消息
                message_at = Message()
                message_at.type = MsType.AT
                message_at.data = MsData(qq=user_id)
                # 创建文本消息
                message_text = Message()
                message_text.type = MsType.TEXT
                message_text.data = MsData(text='\n' + res.message)
                self.message_api.send_group_msg(group_id, [message_at, message_text])
            elif self.message_report.message_type == MessageType.PRIVATE:
                # 回复·私聊消息
                # 发送私聊消息
                message = Message()
                message.type = MsType.TEXT
                data = MsData()
                data.text = '\n' + res.message
                message.data = data
                self.message_api.send_private_msg(user_id, [message])
        # 清除缓存
        shutil.rmtree(config_path)
